import produce from "immer";
/**
 *
 * @param {*} initialState 初始状态
 * @param {*} reducers
 * @param {*} extraReducers
 * @returns
 */

function createReducer(initialState, reducers, extraReducers) {
  //用于存储每种action类型对应的处理函数
  const actionsMap = new Map();
  const builder = {
    addCase(actionCreator, reducer) {
      //把动作类型和对应的状态计算函数进行了关联
      actionsMap.set(actionCreator.type, reducer);
      return this;
    },
  };
  extraReducers(builder);
  // 返回函数会通过  闭包 把 reducers 缓存住
  return function (state = initialState, action) {
    // 如果是同步的
    const reducer = reducers[action.type];
    if (reducer) {
      return produce(state, (draft) => {
        reducer(draft, action);
      });
    }
    const caseReducer = actionsMap.get(action.type);
    // 如果是异步的
    if (caseReducer) {
      return produce(state, (draft) => {
        caseReducer(draft, action);
      });
    }
    return state;
  };
}

/**
 *
 * 初版
 *
 * @param {*} initialState 初始状态
 * @param {*} builderCallback
 * @returns
 */

function createReducer2(initialState, builderCallback) {
  //用于存储每种action类型对应的处理函数
  const actionsMap = new Map();
  const builder = {
    addCase(actionCreator, reducer) {
      //把动作类型和对应的状态计算函数进行了关联
      actionsMap.set(actionCreator.type, reducer);
      return this;
    },
  };
  // 1. 执行回调函数，实现 action.type 和 reducer 对应 map 关系
  builderCallback(builder);
  // 2. 返回 包装过的 reducer

  // 这个  reducer 会去 map，取出传入的 reducer，用 produce 执行，返回一个值
  return function reducer(state = initialState, action) {
    const caseReducer = actionsMap.get(action.type);
    if (caseReducer) {
      return produce(state, (draft) => {
        // 处理过后  action
        caseReducer(draft, action);
      });
    }
    return state;
  };
}

export default createReducer;
